package org.jeecg.modules.demo.gmslopedata.controller;


import java.io.*;
import java.lang.ref.SoftReference;
import java.lang.reflect.InvocationTargetException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.*;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;


import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.shiro.SecurityUtils;
import org.geotools.data.DataStore;
import org.geotools.data.DataStoreFinder;
import org.geotools.data.FeatureSource;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.geotools.filter.text.ecql.ECQL;
import org.geotools.geometry.jts.JTS;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.geotools.referencing.CRS;
import org.jeecg.common.api.dto.message.MessageDTO;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.WebsocketConst;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.query.QueryRuleEnum;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.demo.gmAdministrativeCode.entity.GmAdministrativeCode;
import org.jeecg.modules.demo.gmAdministrativeCode.service.IGmAdministrativeCodeService;
import org.jeecg.modules.demo.gmAlgorithmSetting.service.IGmAlgorithmSettingService;
import org.jeecg.modules.demo.gmslopedata.entity.EvaluateCountDTO;
import org.jeecg.modules.demo.gmslopedata.entity.GmSlopeData;
import org.jeecg.modules.demo.gmslopedata.entity.GmSlopeDataVoScreen;
import org.jeecg.modules.demo.gmslopedata.service.IGmSlopeDataService;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;


import org.jeecg.modules.demo.gmslopedata1.entity.GmSlopeData1;
import org.jeecg.modules.demo.gmslopedata1.service.IGmSlopeData1Service;
import org.jeecg.modules.demo.gmtreatmentmeasures.entity.GmTreatmentMeasures;
import org.jeecg.modules.demo.gmtreatmentmeasures.service.IGmTreatmentMeasuresService;

import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.modules.message.websocket.WebSocket;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.service.ISysUserService;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Point;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.filter.Filter;

import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.*;

import org.springframework.web.servlet.ModelAndView;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.apache.shiro.authz.annotation.RequiresPermissions;

 /**
 * @Description: 边坡数据
 * @Author: jeecg-boot
 * @Date:   2025-06-21
 * @Version: V1.0
 */
@Api(tags="边坡数据")
@RestController
@RequestMapping("/gmslopedata/gmSlopeData")
@Slf4j
public class GmSlopeDataController extends JeecgController<GmSlopeData, IGmSlopeDataService> {
	 @Autowired
	 private IGmSlopeDataService gmSlopeDataService;
     @Autowired
	 private IGmAlgorithmSettingService gmAlgorithmSettingService;

	 @Autowired
	 private IGmTreatmentMeasuresService gmTreatmentMeasuresService;

	 @Autowired
	 private IGmAdministrativeCodeService gmAdministrativeCodeService;

	 @Autowired
	 private ISysBaseAPI sysBaseAPI;

	 // 注入自定义线程池
	 @Autowired
	 @Qualifier("gmDataThreadPool")
	 private ThreadPoolTaskExecutor taskExecutor;
	 @Autowired
	 private WebSocket webSocket;
	 @Autowired
	 private ISysUserService sysUserService;

	
	/**
	 * 分页列表查询
	 *
	 * @param gmSlopeData
	 * @param pageNo
	 * @param pageSize
	 * @param req
	 * @return
	 */
	//@AutoLog(value = "边坡数据-分页列表查询")
	@ApiOperation(value="边坡数据-分页列表查询", notes="边坡数据-分页列表查询")
	@GetMapping(value = "/list")
	public Result<IPage<GmSlopeData>> queryPageList(GmSlopeData gmSlopeData,
								   @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
								   @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
								   HttpServletRequest req) {
		// 自定义查询规则
		Map<String, QueryRuleEnum> customeRuleMap = new HashMap<>();
		// 自定义多选的查询规则为：LIKE_WITH_OR
		customeRuleMap.put("county", QueryRuleEnum.LIKE_WITH_OR);
		customeRuleMap.put("town", QueryRuleEnum.LIKE_WITH_OR);
		customeRuleMap.put("village", QueryRuleEnum.LIKE_WITH_OR);
		customeRuleMap.put("team", QueryRuleEnum.LIKE_WITH_OR);
		customeRuleMap.put("patchNumber", QueryRuleEnum.LIKE_WITH_OR);
		customeRuleMap.put("position", QueryRuleEnum.LIKE_WITH_OR);
		customeRuleMap.put("threatHouse", QueryRuleEnum.LIKE_WITH_OR);
		customeRuleMap.put("householder", QueryRuleEnum.LIKE_WITH_OR);
		customeRuleMap.put("obligee", QueryRuleEnum.LIKE_WITH_OR);
        QueryWrapper<GmSlopeData> queryWrapper = QueryGenerator.initQueryWrapper(gmSlopeData, req.getParameterMap(),customeRuleMap);
		LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
		String roleCode = sysUser.getRoleCode();
//		System.out.println("sysUser.getUsername() = " + sysUser.getUsername());
//		System.out.println("sysUser.getRealname() = " + sysUser.getRealname());
//		System.out.println("roleCode = " + roleCode);
		switch (roleCode) {
			case  "admin":
				break;
			//如果是区县就查询当前曲线下的所有数据
			case "county":
				queryWrapper.eq("county", sysUser.getCounty());
				break;
			case "town":
//				System.out.println("sysUser.getCounty() = " + sysUser.getCounty());
//				System.out.println("sysUser.getTown() = " + sysUser.getTown());
				queryWrapper.eq("county", sysUser.getCounty());
				queryWrapper.eq("town", sysUser.getTown());
				break;
			case "village":
				queryWrapper.eq("create_by", sysUser.getUsername());
				break;
		}
		IPage<GmSlopeData> pageList;

		if (pageSize == null || pageSize <= 0) {
			// 返回所有数据，不进行分页
			List<GmSlopeData> list = gmSlopeDataService.list(queryWrapper);
			// 使用一个自定义的 SimpleIPage 来包装结果（或使用 Page 的构造方法）
			pageList = new Page<>();
			((Page<GmSlopeData>) pageList).setRecords(list);
			((Page<GmSlopeData>) pageList).setTotal(list.size());
			((Page<GmSlopeData>) pageList).setSize(Integer.MAX_VALUE); // 表示一次性返回所有
			((Page<GmSlopeData>) pageList).setCurrent(1);
		} else {
			// 正常分页查询
			Page<GmSlopeData> page = new Page<>(pageNo, pageSize);
			pageList = gmSlopeDataService.page(page, queryWrapper);
		}
		return Result.OK(pageList);
	}
	 /**
	  * 查询登录用户的地理位置信息
	  *
	  */
	 @ApiOperation(value="查询登录用户的地理位置信息", notes="查询登录用户的地理位置信息")
	 @GetMapping(value = "/getLocation")
	 public Result<Map<String, Object>> getLocation(HttpServletRequest req) {
		 Result<Map<String, Object>> result = new Result<>();
		 LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
		 Map<String, Object> resMap = new HashMap<String, Object>(5);
		 resMap.put("province", sysUser.getProvince());
		 resMap.put("city", sysUser.getCity());
		 resMap.put("county", sysUser.getCounty());
		 resMap.put("town", sysUser.getTown());
		 resMap.put("village", sysUser.getVillage());
		 result.setResult(resMap);
		 return result;
	 }

	 /**
	  * 查询大屏数据
	  *
	  * @param gmSlopeData
	  * @param req
	  * @return
	  */
	 //@AutoLog(value = "边坡数据-分页列表查询")
	 @ApiOperation(value="边坡数据-查询大屏数据", notes="边坡数据-查询大屏数据")
	 @GetMapping(value = "/listLargeScreen")
	 public Result<List<GmSlopeDataVoScreen>> listLargeScreen(GmSlopeData gmSlopeData,
															   HttpServletRequest req) throws InvocationTargetException, IllegalAccessException {

		 QueryWrapper<GmSlopeData> queryWrapper = QueryGenerator.initQueryWrapper(gmSlopeData, req.getParameterMap());
		 LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
		 String roleCode = sysUser.getRoleCode();
		 switch (roleCode) {
			 case  "admin":
				 break;
			 //如果是区县就查询当前曲线下的所有数据
			 case "county":
				 queryWrapper.eq("county", sysUser.getCounty());
				 break;
			 case "town":
				 queryWrapper.eq("county", sysUser.getCounty());
				 queryWrapper.eq("town", sysUser.getTown());
				 break;
			 case "village":
//				 queryWrapper.eq("town", sysUser.getTown());
				 queryWrapper.eq("create_by", sysUser.getUsername());
				 break;
		 }
		 if (roleCode.equals("admin")) {
             queryWrapper.eq("village", gmSlopeData.getVillage());
		 }
		 else {
			 return Result.error("权限不足");
		 }
		 // 返回所有数据，不进行分页
		 List<GmSlopeData> list = gmSlopeDataService.list(queryWrapper);
		 //赋值数据给GmSlopeDataVoScreen
		 List<GmSlopeDataVoScreen> listScreen = new ArrayList<>();
		 for (GmSlopeData slopeData : list) {
			 GmSlopeDataVoScreen gmSlopeDataVoScreen = new GmSlopeDataVoScreen();
             BeanUtils.copyProperties(slopeData,gmSlopeDataVoScreen);
             listScreen.add(gmSlopeDataVoScreen);
		 }
		 return Result.OK(listScreen);
	 }

	 /**
	  * 分页列表申请修改记录
	  *
	  * @param gmSlopeData
	  * @param pageNo
	  * @param pageSize
	  * @param req
	  * @return
	  */
	 //@AutoLog(value = "边坡数据-分页列表查询")
	 @ApiOperation(value="边坡数据-分页列表申请修改记录", notes="边坡数据-分页列表申请修改记录")
	 @GetMapping(value = "/listUpdate")
	 public Result<IPage<GmSlopeData>> listUpdate(GmSlopeData gmSlopeData,
													 @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
													 @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
													 HttpServletRequest req) {
		 // 自定义查询规则
		 Map<String, QueryRuleEnum> customeRuleMap = new HashMap<>();
		 // 自定义多选的查询规则为：LIKE_WITH_OR
		 customeRuleMap.put("county", QueryRuleEnum.LIKE_WITH_OR);
		 customeRuleMap.put("town", QueryRuleEnum.LIKE_WITH_OR);
		 customeRuleMap.put("village", QueryRuleEnum.LIKE_WITH_OR);
		 customeRuleMap.put("team", QueryRuleEnum.LIKE_WITH_OR);
		 customeRuleMap.put("patchNumber", QueryRuleEnum.LIKE_WITH_OR);
		 customeRuleMap.put("position", QueryRuleEnum.LIKE_WITH_OR);
		 customeRuleMap.put("threatHouse", QueryRuleEnum.LIKE_WITH_OR);
		 customeRuleMap.put("householder", QueryRuleEnum.LIKE_WITH_OR);
		 customeRuleMap.put("obligee", QueryRuleEnum.LIKE_WITH_OR);
		 QueryWrapper<GmSlopeData> queryWrapper = QueryGenerator.initQueryWrapper(gmSlopeData, req.getParameterMap(),customeRuleMap);
		 LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
		 String roleCode = sysUser.getRoleCode();
		 switch (roleCode) {
			 case  "admin":
				 break;
//			case  "user":
//				queryWrapper.eq("create_by", sysUser.getUsername());
//				break;
			 //如果是区县就查询当前曲线下的所有数据
			 case "county":
				 queryWrapper.eq("county", sysUser.getCounty());
				 break;
			 case "town":
				 queryWrapper.eq("county", sysUser.getCounty());
				 queryWrapper.eq("town", sysUser.getTown());
				 break;
			 case "village":
//				 queryWrapper.eq("town", sysUser.getTown());
				 queryWrapper.eq("create_by", sysUser.getUsername());
//				queryWrapper.eq("village", sysUser.getVillage());
				 break;
		 }
		 queryWrapper.ne("is_update", "0");
		 Page<GmSlopeData> page = new Page<GmSlopeData>(pageNo, pageSize);
		 IPage<GmSlopeData> pageList = gmSlopeDataService.page(page, queryWrapper);

		 return Result.OK(pageList);
	 }

	 @ApiOperation(value="边坡数据-边坡治理方案", notes="边坡数据-边坡治理方案")
	 @GetMapping(value = "/listMeasure")
	 public Result<IPage<GmSlopeData>> listMeasure(GmSlopeData gmSlopeData,
													 @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
													 @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
													 HttpServletRequest req) {
		 // 自定义查询规则
		 Map<String, QueryRuleEnum> customeRuleMap = new HashMap<>();
		 // 自定义多选的查询规则为：LIKE_WITH_OR
		 customeRuleMap.put("county", QueryRuleEnum.LIKE_WITH_OR);
		 customeRuleMap.put("town", QueryRuleEnum.LIKE_WITH_OR);
		 customeRuleMap.put("village", QueryRuleEnum.LIKE_WITH_OR);
		 customeRuleMap.put("team", QueryRuleEnum.LIKE_WITH_OR);
		 customeRuleMap.put("number", QueryRuleEnum.LIKE_WITH_OR);
		 customeRuleMap.put("patchNumber", QueryRuleEnum.LIKE_WITH_OR);
		 customeRuleMap.put("position", QueryRuleEnum.LIKE_WITH_OR);
		 customeRuleMap.put("threatHouse", QueryRuleEnum.LIKE_WITH_OR);
		 customeRuleMap.put("householder", QueryRuleEnum.LIKE_WITH_OR);
		 customeRuleMap.put("obligee", QueryRuleEnum.LIKE_WITH_OR);
		 QueryWrapper<GmSlopeData> queryWrapper = QueryGenerator.initQueryWrapper(gmSlopeData, req.getParameterMap(),customeRuleMap);
		 //查询result字段为“欠稳定”或“不稳定”的数据
		 queryWrapper.in("result", "欠稳定", "不稳定");
		 //获取当前登录用户
		 LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
		 String roleCode = sysUser.getRoleCode();
		 switch (roleCode) {
			 case  "admin":
				 break;
			 //如果是区县就查询当前区县下的所有数据
			 case "county":
				 queryWrapper.eq("county", sysUser.getCounty());
				 break;
			 case "town":
				 queryWrapper.eq("county", sysUser.getCounty());
				 queryWrapper.eq("town", sysUser.getTown());
				 break;
			 case "village":
				 queryWrapper.eq("create_by", sysUser.getUsername());
				 System.out.println("roleCode = " + roleCode);
				 break;
		 }
		 Page<GmSlopeData> page = new Page<GmSlopeData>(pageNo, pageSize);
		 IPage<GmSlopeData> pageList = gmSlopeDataService.page(page, queryWrapper);
		 return Result.OK(pageList);
	 }


	 /**
	  * @param gmSlopeData
	  * @param pageNo
	  * @param pageSize
	  * @param req
	  * @return
	  */
	 @ApiOperation(value="边坡数据-分页列表查询", notes="边坡数据-分页列表查询")
	 @GetMapping(value = "/listEvaluate")
	 public Result<IPage<GmSlopeData>> queryPageListEvaluate(GmSlopeData gmSlopeData,
													  @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
													  @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
													  HttpServletRequest req) {
		 // 自定义查询规则
		 Map<String, QueryRuleEnum> customeRuleMap = new HashMap<>();
		 // 自定义多选的查询规则为：LIKE_WITH_OR
		 customeRuleMap.put("county", QueryRuleEnum.LIKE_WITH_OR);
		 customeRuleMap.put("town", QueryRuleEnum.LIKE_WITH_OR);
		 customeRuleMap.put("village", QueryRuleEnum.LIKE_WITH_OR);
		 customeRuleMap.put("team", QueryRuleEnum.LIKE_WITH_OR);
		 customeRuleMap.put("patchNumber", QueryRuleEnum.LIKE_WITH_OR);
		 customeRuleMap.put("position", QueryRuleEnum.LIKE_WITH_OR);
		 customeRuleMap.put("threatHouse", QueryRuleEnum.LIKE_WITH_OR);
		 customeRuleMap.put("householder", QueryRuleEnum.LIKE_WITH_OR);
		 customeRuleMap.put("obligee", QueryRuleEnum.LIKE_WITH_OR);
		 QueryWrapper<GmSlopeData> queryWrapper = QueryGenerator.initQueryWrapper(gmSlopeData, req.getParameterMap(),customeRuleMap);

		 LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
		 String roleCode = sysUser.getRoleCode();
		 switch (roleCode) {
			 case  "admin":
				 break;
//			case  "user":
//				queryWrapper.eq("create_by", sysUser.getUsername());
//				break;
			 //如果是区县就查询当前曲线下的所有数据
			 case "county":
				 queryWrapper.eq("county", sysUser.getCounty());
				 break;
			 case "town":
				 queryWrapper.eq("county", sysUser.getCounty());
				 queryWrapper.eq("town", sysUser.getTown());
				 break;
			 case "village":
				 queryWrapper.eq("create_by", sysUser.getUsername());
//				 queryWrapper.and(wrapper -> wrapper.eq("village", sysUser.getVillage())
//						 .or()
//						 .eq("create_by", sysUser.getUsername()));

//				queryWrapper.eq("village", sysUser.getVillage());
				 break;
		 }

		 //查询flag字段为1
		 queryWrapper.eq("flag", "1");
		 Page<GmSlopeData> page = new Page<GmSlopeData>(pageNo, pageSize);
		 IPage<GmSlopeData> pageList = gmSlopeDataService.page(page, queryWrapper);
//		 pageList.getRecords().forEach(item -> {
//			 System.out.println("item.getFlag() = " + item.getFlag());
//		 });
		 return Result.OK(pageList);
	 }
//	 @ApiOperation(value = "边坡数据-评价结果数据统计", notes = "边坡数据-评价结果数据统计")
//	 @GetMapping("/queryEvaluate")
//	 public Result<Map<String, Integer>> queryEvaluate(GmSlopeData gmSlopeData, HttpServletRequest req) {
//
//		 Map<String, QueryRuleEnum> customRuleMap = new HashMap<>();
//		 customRuleMap.put("county", QueryRuleEnum.LIKE_WITH_OR);
//		 customRuleMap.put("town", QueryRuleEnum.LIKE_WITH_OR);
//		 customRuleMap.put("village", QueryRuleEnum.LIKE_WITH_OR);
//		 customRuleMap.put("team", QueryRuleEnum.LIKE_WITH_OR);
//		 customRuleMap.put("patchNumber", QueryRuleEnum.LIKE_WITH_OR);
//		 customRuleMap.put("position", QueryRuleEnum.LIKE_WITH_OR);
//		 customRuleMap.put("threatHouse", QueryRuleEnum.LIKE_WITH_OR);
//		 customRuleMap.put("householder", QueryRuleEnum.LIKE_WITH_OR);
//		 customRuleMap.put("obligee", QueryRuleEnum.LIKE_WITH_OR);
//		 QueryWrapper<GmSlopeData> queryWrapper = QueryGenerator.initQueryWrapper(gmSlopeData, req.getParameterMap(), customRuleMap);
//
//		 LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
//		 String roleCode = sysUser.getRoleCode();
//
//		 switch (roleCode) {
//			 case "county":
//				 queryWrapper.eq("county", sysUser.getCounty());
//				 break;
//			 case "town":
//				 queryWrapper.eq("county", sysUser.getCounty());
//				 queryWrapper.eq("town", sysUser.getTown());
//				 break;
//			 case "village":
//				 queryWrapper.eq("create_by", sysUser.getUsername());
//				 break;
//		 }
//
//		 queryWrapper.eq("flag", "1");
//
//		 // 3. 统计总数（使用原始条件）
//		 long total = gmSlopeDataService.count(queryWrapper);
//
//		 // 4. 创建分组查询（复制基础条件）
//		 QueryWrapper<GmSlopeData> groupWrapper = queryWrapper.clone();
//		 groupWrapper
//				 .select("result", "COUNT(*) AS count") // 选择结果列和计数
//				 .groupBy("result");                    // 按结果分组
//
//		 // 执行查询
//		 List<Map<String, Object>> resultMaps = gmSlopeDataService.listMaps(groupWrapper);
//		 // 转换为 Map<result, count>
//		 Map<String, Integer> statistics = new HashMap<>();
//		 statistics.put("稳定", 0);
//		 statistics.put("基本稳定", 0);
//		 statistics.put("欠稳定", 0);
//		 statistics.put("不稳定", 0);
//
//		 for (Map<String, Object> map : resultMaps) {
//			 String result = (String) map.get("result");
//			 Long count = (Long) map.get("count");
//
//			 if ("稳定".equals(result)) {
//				 statistics.put("稳定", count.intValue());
//			 } else if ("基本稳定".equals(result)) {
//				 statistics.put("基本稳定", count.intValue());
//			 } else if ("欠稳定".equals(result)) {
//				 statistics.put("欠稳定", count.intValue());
//			 } else if ("不稳定".equals(result)) {
//				 statistics.put("不稳定", count.intValue());
//			 }
//		 }
//
//		 // 补充 total 数量（可选）
////		 Integer total = Math.toIntExact(gmSlopeDataService.count(queryWrapper));
//		 statistics.put("total", (int) total);
//
//		 return Result.OK(statistics);
//	 }
    @ApiOperation(value = "边坡数据-评价结果数据统计", notes = "统计边坡数据中各评价结果的分布及准确率")
    @GetMapping("/queryEvaluate")
    public Result<Map<String, Object>> queryEvaluate(GmSlopeData gmSlopeData, HttpServletRequest req) {

		// 直接调用Service层的方法，将业务逻辑委托出去

		Map<String, Object> statisticsResult = gmSlopeDataService.getEvaluateStatistics(gmSlopeData, req.getParameterMap());

		return Result.OK(statisticsResult);

   }

	 /**
	  * 	不会进行前端条件筛选
	  * @param gmSlopeData
	  * @param req
	  * @return
	  */
	 @ApiOperation(value = "边坡数据-评价结果数据统计", notes = "边坡数据-评价结果数据统计")
	 @GetMapping("/queryEvaluate1")
	 public Result<Map<String, Integer>> queryEvaluate1(GmSlopeData gmSlopeData, HttpServletRequest req) {

		 Map<String, QueryRuleEnum> customRuleMap = new HashMap<>();
		 customRuleMap.put("county", QueryRuleEnum.LIKE_WITH_OR);
		 customRuleMap.put("town", QueryRuleEnum.LIKE_WITH_OR);
		 customRuleMap.put("village", QueryRuleEnum.LIKE_WITH_OR);
		 customRuleMap.put("team", QueryRuleEnum.LIKE_WITH_OR);
		 customRuleMap.put("patchNumber", QueryRuleEnum.LIKE_WITH_OR);
		 customRuleMap.put("position", QueryRuleEnum.LIKE_WITH_OR);
		 customRuleMap.put("threatHouse", QueryRuleEnum.LIKE_WITH_OR);
		 customRuleMap.put("householder", QueryRuleEnum.LIKE_WITH_OR);
		 customRuleMap.put("obligee", QueryRuleEnum.LIKE_WITH_OR);

		 QueryWrapper<GmSlopeData> queryWrapper = QueryGenerator.initQueryWrapper(gmSlopeData, req.getParameterMap(), customRuleMap);

		 LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
		 String roleCode = sysUser.getRoleCode();

		 String county = null, town = null, createBy = null;
		 switch (roleCode) {
			 case "county":
				 county = sysUser.getCounty();
				 break;
			 case "town":
				 town = sysUser.getTown();
				 break;
			 case "village":
				 createBy = sysUser.getUsername();
				 break;
		 }

		 // 查询flag字段为1
		 queryWrapper.eq("flag", "1");

		 // 获取总数
//		 int total = (int) gmSlopeDataService.count(queryWrapper);

		 // 获取各状态数量
		 List<EvaluateCountDTO> dtos = gmSlopeDataService.countEvaluateResults(county, town, createBy);

		 Map<String, Integer> statistics = new HashMap<>();
//		 statistics.put("total", total);
		 statistics.put("稳定", 0);
		 statistics.put("基本稳定", 0);
		 statistics.put("欠稳定", 0);
		 statistics.put("不稳定", 0);

		 for (EvaluateCountDTO dto : dtos) {
			 if ("稳定".equals(dto.getResult())) {
				 statistics.put("稳定", dto.getCount());
			 } else if ("基本稳定".equals(dto.getResult())) {
				 statistics.put("基本稳定", dto.getCount());
			 } else if ("欠稳定".equals(dto.getResult())) {
				 statistics.put("欠稳定", dto.getCount());
			 } else if ("不稳定".equals(dto.getResult())) {
				 statistics.put("不稳定", dto.getCount());
			 }
		 }
		 return Result.OK(statistics);
	 }




	 /**
	  * 评价结果数据统计  小数据量
	  * @param gmSlopeData
	  * @param req
	  * @return
	  */

	 @ApiOperation(value="边坡数据-评价结果数据统计", notes="边坡数据-评价结果数据统计")
	 @GetMapping(value = "/queryEvaluateThread")
	 public Result<Map<String, Integer>> queryEvaluateThread(GmSlopeData gmSlopeData, HttpServletRequest req) {
		  AtomicInteger stableCount = new AtomicInteger(0);
		  AtomicInteger relativelyStableCount = new AtomicInteger(0);
		  AtomicInteger relativelyUnstableCount = new AtomicInteger(0);
		  AtomicInteger unstableCount = new AtomicInteger(0);
		 // 自定义查询规则
		 Map<String, QueryRuleEnum> customeRuleMap = new HashMap<>();
		 // 自定义多选的查询规则为：LIKE_WITH_OR
		 customeRuleMap.put("county", QueryRuleEnum.LIKE_WITH_OR);
		 customeRuleMap.put("town", QueryRuleEnum.LIKE_WITH_OR);
		 customeRuleMap.put("village", QueryRuleEnum.LIKE_WITH_OR);
		 customeRuleMap.put("team", QueryRuleEnum.LIKE_WITH_OR);
		 customeRuleMap.put("patchNumber", QueryRuleEnum.LIKE_WITH_OR);
		 customeRuleMap.put("position", QueryRuleEnum.LIKE_WITH_OR);
		 customeRuleMap.put("threatHouse", QueryRuleEnum.LIKE_WITH_OR);
		 QueryWrapper<GmSlopeData> queryWrapper = QueryGenerator.initQueryWrapper(gmSlopeData, req.getParameterMap(),customeRuleMap);

		 LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
		 String roleCode = sysUser.getRoleCode();
		 switch (roleCode) {
			 //如果是区县就查询当前曲线下的所有数据
			 case "county":
				 queryWrapper.eq("county", sysUser.getCounty());
				 break;
			 case "town":
				 queryWrapper.eq("county", sysUser.getCounty());
				 queryWrapper.eq("town", sysUser.getTown());
				 break;
			 case "village":
				 queryWrapper.eq("create_by", sysUser.getUsername());
				 break;
		 }
		 //查询flag字段为1
		 queryWrapper.eq("flag", "1");
		 List<GmSlopeData> list = gmSlopeDataService.list(queryWrapper);
		 // 添加统计信息
		 Map<String, Integer> statistics = new HashMap<>();
		 statistics.put("total", list.size());
//		 多线程获取每一条数据里面的result字段，统计每一种的个数、
		 Future<?> future = taskExecutor.submit(() -> {
			 list.forEach(item -> {
				 String status = item.getResult();
				 if ("稳定".equals(status)) {
					 stableCount.incrementAndGet();
				 } else if ("基本稳定".equals(status)) {
					 relativelyStableCount.incrementAndGet();
				 } else if ("欠稳定".equals(status)) {
					 relativelyUnstableCount.incrementAndGet();
				 } else if ("不稳定".equals(status)) {
					 unstableCount.incrementAndGet();
				 }
			 });
		 });

		 try {
			 future.get(); // 阻塞等待任务完成
		 } catch (InterruptedException | ExecutionException e) {
			 log.error("统计任务执行失败", e);
			 return Result.error("统计失败");
		 }
		 // 构建返回结果
//		 statistics.put("total", list.size());
		 statistics.put("稳定", stableCount.get());
		 statistics.put("基本稳定", relativelyStableCount.get());
		 statistics.put("欠稳定", relativelyUnstableCount.get());
		 statistics.put("不稳定", unstableCount.get());
		 return Result.OK(statistics);
	 }

	 //		 customeRuleMap.put("slopeType", QueryRuleEnum.LIKE_WITH_OR);
//		 customeRuleMap.put("soilLooseness", QueryRuleEnum.LIKE_WITH_OR);
//		 customeRuleMap.put("overlyingSoilType", QueryRuleEnum.LIKE_WITH_OR);
//		 customeRuleMap.put("rockCharacteristics", QueryRuleEnum.LIKE_WITH_OR);
//		 customeRuleMap.put("fractureDevelopmentDegree", QueryRuleEnum.LIKE_WITH_OR);
//		 customeRuleMap.put("cutSlopeHeight", QueryRuleEnum.LIKE_WITH_OR);
//		 customeRuleMap.put("cutSlopeGradient", QueryRuleEnum.LIKE_WITH_OR);
//		 customeRuleMap.put("cutSlopeShape", QueryRuleEnum.LIKE_WITH_OR);
//		 customeRuleMap.put("naturalSlopeGradient", QueryRuleEnum.LIKE_WITH_OR);
//		 customeRuleMap.put("vegetationCoverage", QueryRuleEnum.LIKE_WITH_OR);
//		 customeRuleMap.put("governanceMeasures", QueryRuleEnum.LIKE_WITH_OR);
//		 customeRuleMap.put("slopeWallDistance", QueryRuleEnum.LIKE_WITH_OR);
//		 customeRuleMap.put("cutSlopeWidth", QueryRuleEnum.LIKE_WITH_OR);
//		 customeRuleMap.put("cutSlopeTime", QueryRuleEnum.LIKE_WITH_OR);
//		 customeRuleMap.put("resident", QueryRuleEnum.LIKE_WITH_OR);
//		 customeRuleMap.put("threatPopulation", QueryRuleEnum.LIKE_WITH_OR);




	 /**
	  *  批量删除
	  *
	  * @param ids
	  * @return
	  */
	 @AutoLog(value = "边坡数据-根据id查询")
	 @ApiOperation(value="边坡数据-根据id查询", notes="边坡数据-根据id查询")
	 @GetMapping(value = "/selectByIds")
	 public Result<IPage<GmTreatmentMeasures>> selectByIds(@RequestParam(name="ids",required=true) String ids,
														   @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
												   @RequestParam(name="pageSize", defaultValue="10") Integer pageSize) {
		 Page<GmTreatmentMeasures> page = new Page<GmTreatmentMeasures>(pageNo, pageSize);
		 QueryWrapper<GmTreatmentMeasures> queryWrapper = new QueryWrapper<>();
		 queryWrapper.in("id", Arrays.asList(ids.split(",")));
		 IPage<GmTreatmentMeasures> pageList = gmTreatmentMeasuresService.page(page, queryWrapper);
		 return Result.OK(pageList);
	 }


//	 @AutoLog(value = "边坡数据-根据village查询边坡个数")
//	 @ApiOperation(value="边坡数据-根据village查询边坡个数", notes="边坡数据-根据village查询边坡个数")
//	 @GetMapping(value = "/getSlopeCount")
//	 public Result<String> getSlopeCount(@RequestParam(name="village", required = true) String village) {
//		 LambdaQueryWrapper<GmSlopeData> queryWrapper = new LambdaQueryWrapper<>();
//		 queryWrapper.eq(GmSlopeData::getVillage, village);
//		 int count = (int) gmSlopeDataService.count(queryWrapper);
//		 // 格式化为4位，不足补零
//		 String formattedCount = String.format("%04d", count+1);
//		 return Result.OK(formattedCount);
//	 }




	 @AutoLog(value = "边坡数据-根据position查询边坡个数-新增专用")
	 @ApiOperation(value="边坡数据-根据position查询边坡个数-新增专用", notes="边坡数据-根据position查询边坡个数-新增专用")
	 @GetMapping(value = "/getSlopeCount2")
	 public Result<String> getSlopeCount2(@RequestParam(name="town", required = true) String town,
										 @RequestParam(name="village", required = true)String village) {
		 LambdaQueryWrapper<GmSlopeData> queryWrapper = new LambdaQueryWrapper<>();
		 queryWrapper.eq(GmSlopeData::getTown, town)
				 .eq(GmSlopeData::getType, "B")
				 .eq(GmSlopeData::getVillage, village);
		 int count = (int) gmSlopeDataService.count(queryWrapper);
		 String code = gmAdministrativeCodeService.getCodeByPosition(town, village);
		 // 格式化为4位，不足补零
		 String formattedCount = String.format("%04d", count+1);
		 String number = code +'B'+formattedCount;
		 return Result.OK(number);
	 }

	 /**
	  * 异步通过excel导入数据
	  *
	  * @param request
	  * @param response
	  * @return
	  */
	 @RequiresPermissions("gmslopedata:gm_slope_data:importExcel")
	 @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
	 public Result<?> importExcelCustom(HttpServletRequest request, HttpServletResponse response) {
		 asyncImportExcel(request, response);
		 return Result.OK("数据导入成功");
	 }


	 @Async("gmDataThreadPool")
	 public void asyncImportExcel(HttpServletRequest request, HttpServletResponse response) {
		 try {
			 gmSlopeDataService.importExcelCustom(request, response, GmSlopeData.class);
		 } catch (Exception e) {
			 log.error("Error during importing Excel data asynchronously", e);
		 }
	 }
	/**
	 *   添加
	 *
	 * @param gmSlopeData
	 * @return
	 */
	@AutoLog(value = "边坡数据-添加")
	@ApiOperation(value="边坡数据-添加", notes="边坡数据-添加")
	@RequiresPermissions("gmslopedata:gm_slope_data:add")
	@PostMapping(value = "/add")
	public Result<String> add(@RequestBody GmSlopeData gmSlopeData) {
		gmSlopeData.setIsUpdate("0");
		gmSlopeDataService.save(gmSlopeData);
		return Result.OK("添加成功！");
	}




	 /**
	  *   获取评价及治理方案
	  *
	  * @param gmSlopeData
	  * @return
	  */
	 @AutoLog(value = "边坡数据-获取评价及治理方案")
	 @ApiOperation(value="边坡数据-获取评价及治理方案", notes="边坡数据-获取评价及治理方案")
	 @PostMapping(value = "/getMeasure")
	 public Result<String> getMeasure(@RequestBody GmSlopeData gmSlopeData) {
		 gmSlopeDataService.calculateYValues(gmSlopeData);
		 return Result.OK("获取评价及治理方案成功！");
	 }


	 /**
	 *  编辑
	 *
	 * @param gmSlopeData
	 * @return
	 */
	@AutoLog(value = "边坡数据-编辑")
	@ApiOperation(value="边坡数据-编辑", notes="边坡数据-编辑")
	@RequiresPermissions("gmslopedata:gm_slope_data:edit")
	@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
	public Result<String> edit(@RequestBody GmSlopeData gmSlopeData) {
		gmSlopeDataService.updateById(gmSlopeData);
		return Result.OK("编辑成功!");
	}

	 /**
	  *  审核
	  *
	  * @param gmSlopeData
	  * @return
	  */
	 @AutoLog(value = "边坡数据-审核")
	 @ApiOperation(value="边坡数据-审核", notes="边坡数据-审核")
	 @RequiresPermissions("gmslopedata:gm_slope_data:audit")
	 @RequestMapping(value = "/audit", method = {RequestMethod.PUT,RequestMethod.POST})
	 public Result<String> audit(@RequestBody GmSlopeData gmSlopeData) {
		 //不同意
		 if (gmSlopeData.getFlag().equals("2")){
//			 String userName = sysBaseAPI.getUserByName(gmSlopeData.getCreateBy()).getUsername();
			 MessageDTO message = new MessageDTO("系统", gmSlopeData.getCreateBy(),
					 "重新填写采集信息",
					 gmSlopeData.getOpinion());
			 sysBaseAPI.sendSysAnnouncement(message);
		 }else{
			 //同意
			 MessageDTO message = new MessageDTO("系统", gmSlopeData.getCreateBy(),
					 "数据审核成功，可以去查看审核评价结果。",
					 gmSlopeData.getOpinion());
			 sysBaseAPI.sendSysAnnouncement(message);
			 gmSlopeData.setOpinion(null);
		 }
		 gmSlopeDataService.updateById(gmSlopeData);
		 SysUser sysUser = sysUserService.getUserByName(gmSlopeData.getCreateBy());
		 JSONObject obj = new JSONObject();
		 obj.put(WebsocketConst.MSG_CMD, "audit");
		 webSocket.sendMessage(sysUser.getId(),obj.toString());
		 return Result.OK("审核完成!");
	 }



//	 /**
//	  *  编辑
//	  *
//	  * @param id
//	  * @return
//	  */
//	 @AutoLog(value = "边坡数据-重新上传")
//	 @ApiOperation(value="边坡数据-重新上传", notes="边坡数据-重新上传")
//	 @RequiresPermissions("gmslopedata:gm_slope_data:reUpload")
//	 @RequestMapping(value = "/reUpload", method = {RequestMethod.PUT,RequestMethod.POST})
//	 public Result<String> reUpload(@RequestParam String id) {
//		 gmSlopeDataService.update(new LambdaUpdateWrapper<GmSlopeData>()
//				 .eq(GmSlopeData::getId, id)
//				 .set(GmSlopeData::getFlag, "0"));
//		 return Result.OK("重新上传!");
//	 }

	 /**
	  *  编辑
	  *
	  * @param gmSlopeData
	  * @return
	  */
	 @AutoLog(value = "边坡数据-重新上传")
	 @ApiOperation(value="边坡数据-重新上传", notes="边坡数据-重新上传")
	 @RequiresPermissions("gmslopedata:gm_slope_data:reUpload")
	 @RequestMapping(value = "/reUpload", method = {RequestMethod.PUT,RequestMethod.POST})
	 public Result<String> reUpload(@RequestBody GmSlopeData gmSlopeData) {
		 gmSlopeDataService.updateById(gmSlopeData);
//		 JSONObject obj = new JSONObject();
//		 obj.put(WebsocketConst.MSG_CMD, "update");
//		 webSocket.sendMessage(obj.toString());
		 return Result.OK("重新上传!");
	 }

	 /**
	  *  申请修改
	  *
	  * @param gmSlopeData
	  * @return
	  */
	 @AutoLog(value = "边坡数据-申请修改")
	 @ApiOperation(value="边坡数据-申请修改", notes="边坡数据-申请修改")
	 @RequiresPermissions("gmslopedata:gm_slope_data:revise")
	 @RequestMapping(value = "/revise", method = RequestMethod.POST)
	 public Result<String> revise(@RequestBody GmSlopeData gmSlopeData) {
		 String id = gmSlopeData.getId();
		 gmSlopeDataService.update(new LambdaUpdateWrapper<GmSlopeData>()
				 .eq(GmSlopeData::getId, id)
				 .set(GmSlopeData::getIsUpdate, "1")
				 .set(GmSlopeData::getApplicationContent, gmSlopeData.getApplicationContent())
		 );
//		 String userName = sysBaseAPI.getUserByName(gmSlopeData.getCreateBy()).getUsername();
//		 MessageDTO message = new MessageDTO("系统", userName,
//		          "申请修改数据，请及时处理。",
//		          gmSlopeData.getOpinion());
//		 JSONObject obj = new JSONObject();
//		 obj.put(WebsocketConst.MSG_CMD, "update");
//		 webSocket.sendMessage(obj.toString());
		 return Result.OK("申请修改!");
	 }

	 /**
	  *  处理申请修改
	  *
	  * @param gmSlopeData
	  * @return
	  */
	 @AutoLog(value = "边坡数据-处理申请修改")
	 @ApiOperation(value="边坡数据-处理申请修改", notes="边坡数据-处理申请修改")
//	 @RequiresPermissions("gmslopedata:gm_slope_data:handlerRevise")
	 @RequestMapping(value = "/handlerRevise", method = RequestMethod.POST)
	 public Result<String> handlerRevise(@RequestBody GmSlopeData gmSlopeData) {
		 String handlerUpdate = gmSlopeData.getIsUpdate();
		 if (handlerUpdate.equals("2")){
			 MessageDTO message = new MessageDTO("系统", gmSlopeData.getCreateBy(),
					 "同意申请修改数据，请及时修改数据。",
					 gmSlopeData.getOpinion());
			 sysBaseAPI.sendSysAnnouncement(message);
//			 gmSlopeData.setUpdateOpinion(null);
		 }else if (handlerUpdate.equals("3")){
			 MessageDTO message = new MessageDTO("系统", gmSlopeData.getCreateBy(),
					 "拒绝申请修改数据!",
					 gmSlopeData.getOpinion());
			 sysBaseAPI.sendSysAnnouncement(message);
		 }
		 gmSlopeDataService.updateById(gmSlopeData);
		 SysUser sysUser = sysUserService.getUserByName(gmSlopeData.getCreateBy());
		 JSONObject obj = new JSONObject();
		 obj.put(WebsocketConst.MSG_CMD, "handlerRevise");
		 webSocket.sendMessage(sysUser.getId(),obj.toString());
		 return Result.OK("申请修改!");
	 }
	
	/**
	 *   通过id删除
	 *
	 * @param id
	 * @return
	 */
	@AutoLog(value = "边坡数据-通过id删除")
	@ApiOperation(value="边坡数据-通过id删除", notes="边坡数据-通过id删除")
	@RequiresPermissions("gmslopedata:gm_slope_data:delete")
	@DeleteMapping(value = "/delete")
	public Result<String> delete(@RequestParam(name="id",required=true) String id) {
		gmSlopeDataService.removeById(id);
		return Result.OK("删除成功!");
	}


	 /**
	  *   通过id删除
	  *
	  * @param id
	  * @return
	  */
	 @AutoLog(value = "边坡数据-通过id删除")
	 @ApiOperation(value="边坡数据-通过id删除", notes="边坡数据-通过id删除")
	 @RequiresPermissions("gmslopedata:gm_slope_data:userDelete")
	 @DeleteMapping(value = "/userDelete")
	 public Result<String> userDelete(@RequestParam(name="id",required=true) String id) {
		 gmSlopeDataService.removeById(id);
		 return Result.OK("删除成功!");
	 }


	
	/**
	 *  批量删除
	 *
	 * @param ids
	 * @return
	 */
	@AutoLog(value = "边坡数据-批量删除")
	@ApiOperation(value="边坡数据-批量删除", notes="边坡数据-批量删除")
	@RequiresPermissions("gmslopedata:gm_slope_data:deleteBatch")
	@DeleteMapping(value = "/deleteBatch")
	public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
		this.gmSlopeDataService.removeByIds(Arrays.asList(ids.split(",")));
		return Result.OK("批量删除成功!");
	}
	
	/**
	 * 通过id查询
	 *
	 * @param id
	 * @return
	 */
	//@AutoLog(value = "边坡数据-通过id查询")
	@ApiOperation(value="边坡数据-通过id查询", notes="边坡数据-通过id查询")
	@GetMapping(value = "/queryById")
	public Result<GmSlopeData> queryById(@RequestParam(name="id",required=true) String id) {
		GmSlopeData gmSlopeData = gmSlopeDataService.getById(id);
		if(gmSlopeData==null) {
			return Result.error("未找到对应数据");
		}
		return Result.OK(gmSlopeData);
	}


    /**
    * 导出excel
    *
    * @param request
    * @param gmSlopeData
    */
    @RequiresPermissions("gmslopedata:gm_slope_data:exportXls")
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, GmSlopeData gmSlopeData) {
        return super.exportXls(request, gmSlopeData, GmSlopeData.class, "边坡数据");
    }

//    /**
//      * 通过excel导入数据
//    *
//    * @param request
//    * @param response
//    * @return
//    */
//    @RequiresPermissions("gmslopedata:gm_slope_data:importExcel")
//    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
//    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
//        return super.importExcel(request, response, GmSlopeData.class);
//    }


//	 /**
//	  * 通过excel导入数据
//	  *
//	  * @param request
//	  * @param response
//	  * @return
//	  */
//	 @RequiresPermissions("gmslopedata:gm_slope_data:importExcel")
//	 @RequestMapping(value = "/importExcelCustom", method = RequestMethod.POST)
//	 public Result<?> importExcelCustom(HttpServletRequest request, HttpServletResponse response) {
//		 return gmSlopeDataService.importExcelCustom(request, response, GmSlopeData.class);
//	 }


//	 @GetMapping("/exportZip")
//	 public void exportZip(HttpServletResponse response) throws Exception {
//		 // 1. 查询数据（实际业务中从数据库获取）
//		 List<GmSlopeData> dataList = gmSlopeDataService.list();
//
//		 // 2. 设置响应头
//		 response.setContentType("application/zip");
//		 response.setHeader("Content-Disposition", "attachment;filename=边坡数据导出.zip");
//
//		 // 3. 写入ZIP流
//		 try (OutputStream os = response.getOutputStream()) {
//			 gmSlopeDataService.exportZip(dataList, os); // 调用上述打包方法
//		 }
//	 }




	 // 引入模板文件存放地址
	 @Value(value = "${gm.template-file}")
	 private String templateLeaveApprovalFile;

	 /**
	  * 导出审批意见Word(模板)
	  * templateLeaveApprovalFile为模板存放路径，请在yml文件中配置
	  * @param request
	  * @param id
	  */
	 @ApiOperation(value="exportWord", notes="exportWord")
	 @GetMapping(value = "/exportWord")
	 public ModelAndView exportWord(HttpServletRequest request, @RequestParam(name="id",required=false) String id) {
		 return gmSlopeDataService.exportWord(id, templateLeaveApprovalFile);
	 }
	 /**
	  * 导出审批意见Word(模板)
	  * templateLeaveApprovalFile为模板存放路径，请在yml文件中配置
	  * @param id
	  */
	 @ApiOperation(value="exportWord", notes="exportWord")
	 @GetMapping(value = "/exportWord1")
	 public Result<byte[]> exportWord1( @RequestParam(name="id",required=false) String id) {
		 return Result.ok(gmSlopeDataService.exportWord1(id, templateLeaveApprovalFile));
	 }

	 // 引入模板文件存放地址
	 @Value(value = "${gm.SockType}")
	 private String SockTypePath;
	 // 引入模板文件存放地址
	 @Value(value = "${gm.GeoType}")
	 private String GeoTypePath;

	 private final LoadingCache<String, DataStore> dataStoreCache1 = CacheBuilder.newBuilder()
			 .maximumSize(10) // 缓存最多10个DataStore实例
			 .expireAfterAccess(10, TimeUnit.MINUTES) // 10分钟后未访问的数据会被移除
			 .build(new CacheLoader<String, DataStore>() {
				 public DataStore load(String filePath) throws Exception {
					 URL url = new File(filePath).toURI().toURL();
					 Map<String, Object> params = new HashMap<>();
					 params.put("url", url);
					 params.put("charset", "GBK");
					 return DataStoreFinder.getDataStore(params);
				 }
	});



	 @ApiOperation(value="selectSockType3", notes="selectSockType3")
	 @PostMapping("/selectSockType3")
	 public Result<Map<String, Object>> selectSockType3(@RequestBody JSONObject jsonObject) throws Exception {
		 double longitude = jsonObject.getDouble("longitude");
		 double latitude = jsonObject.getDouble("latitude");


		 CompletionStage <Map<String, Object>> slopeResult = queryShapefile1(
						 SockTypePath,
						 longitude,
						 latitude,
						 new String[]{"岩类", "岩类名称"},
						 "rockType"
				 );
		 return Result.ok(slopeResult.toString());
	 }
	 @ApiOperation(value="selectGeoType3", notes="selectGeoType3")
	 @PostMapping("/selectGeoType3")
	 public Result<Map<String, Object>> selectGeoType3(@RequestBody JSONObject jsonObject) throws Exception {
		 double longitude = jsonObject.getDouble("longitude");
		 double latitude = jsonObject.getDouble("latitude");


		 CompletionStage <Map<String, Object>> slopeResult = queryShapefile1(
				 GeoTypePath,
				 longitude,
				 latitude,
				 new String[]{"gridcode"},  // 根据实际字段名调整
				 "slope"
		 );
		 return Result.ok(slopeResult.toString());
	 }

	 private CompletionStage<Map<String, Object>> queryShapefile1(String filePath, double longitude, double latitude,
																 String[] attributeNames, String resultKey)
			 throws Exception {
		 Map<String, Object> result = new HashMap<>();
		 List<Map<String, String>> featuresList = new ArrayList<>();

		 DataStore dataStore = dataStoreCache1.get(filePath);
		 if (dataStore == null) {
			 result.put(resultKey + "_error", "无法加载数据源: " + filePath);
			 return (CompletionStage<Map<String, Object>>) result;
		 }

		 String typeName = dataStore.getTypeNames()[0];
		 SimpleFeatureType schema = dataStore.getSchema(typeName);

		 CoordinateReferenceSystem sourceCRS = CRS.decode("EPSG:4326");
		 CoordinateReferenceSystem targetCRS = schema.getCoordinateReferenceSystem();

		 MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS, true);

		 GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
		 Point point = geometryFactory.createPoint(new Coordinate(longitude, latitude));
		 Point transformedPoint = (Point) JTS.transform(point, transform);

		 Filter filter = ECQL.toFilter(
				 "INTERSECTS(the_geom, POINT(" + transformedPoint.getX() + " " + transformedPoint.getY() + "))"
		 );

		 FeatureCollection<SimpleFeatureType, SimpleFeature> features = dataStore.getFeatureSource(typeName).getFeatures(filter);
		 try (FeatureIterator<SimpleFeature> iterator = features.features()) {
			 while (iterator.hasNext()) {
				 SimpleFeature feature = iterator.next();
				 Map<String, String> attributeMap = new HashMap<>();

				 for (String attrName : attributeNames) {
					 Object value = feature.getAttribute(attrName);
					 attributeMap.put(attrName, value != null ? value.toString() : "N/A");
				 }
				 featuresList.add(attributeMap);
			 }
		 }

		 if ("rockType".equals(resultKey)) {
			 String combinedValues = "";
			 for (Map<String, String> attrs : featuresList) {
				 String rockType = attrs.getOrDefault("岩类", "");
				 String rockTypeName = attrs.getOrDefault("岩类名称", "");
				 combinedValues = rockType + " " + rockTypeName.trim();
			 }
			 result.put(resultKey, combinedValues);
		 } else if ("slope".equals(resultKey) && !featuresList.isEmpty()) {
			 String slopeValue = featuresList.get(0).get("gridcode");
			 try {
				 if (slopeValue.equals("1")) {
					 result.put(resultKey, "A 小于20°".trim());
				 } else if (slopeValue.equals("2")) {
					 result.put(resultKey, "B 20°-30°".trim());
				 } else {
					 result.put(resultKey, "C 大于30°".trim());
				 }
			 } catch (NumberFormatException e) {
				 result.put(resultKey, slopeValue);
			 }
		 } else {
			 result.put(resultKey, featuresList);
		 }

		 return (CompletionStage<Map<String, Object>>) result;
	 }





	 @ApiOperation(value="查询岩组类型", notes="查询岩组类型")
	 @PostMapping("/selectSockType1")
	 public Result<Map<String, Object>> queryByPoint1(@RequestBody JSONObject jsonObject) throws Exception {

		 double longitude = jsonObject.getDouble("longitude");
		 System.out.println("longitude = " + longitude);
		 double latitude = jsonObject.getDouble("latitude");
		 System.out.println("latitude = " + latitude);
		 Map<String, Object> result = new HashMap<>();
		 result.put("status", "success");

		 // 设置字符编码为 GBK/GB18030，避免 DBF 文件中中文乱码
		 System.setProperty("org.geotools.referencing.forceXY", "true");
		 Charset charset = Charset.forName("GBK"); // 或 GB18030
		 System.setProperty("dbf.encoding", charset.name());

		 File file = new File(SockTypePath);
		 if (!file.exists()) {
			 result.put("error", "文件不存在");
			 result.put("status", "fail");
			 return  Result.ok(result) ;
		 }

		 Map<String, Object> map = new HashMap<>();
		 map.put("url", file.toURI().toURL());
		 map.put("charset", charset);

		 DataStore dataStore = null;
		 try {
			 dataStore = DataStoreFinder.getDataStore(map);
			 if (dataStore == null) {
				 result.put("error", "无法加载数据源，请检查路径和编码");
				 result.put("status", "fail");
				 return  Result.ok(result) ;
			 }

			 String typeName = dataStore.getTypeNames()[0];
			 SimpleFeatureSource featureSource = dataStore.getFeatureSource(typeName);
			 SimpleFeatureType schema = featureSource.getSchema();

			 // 打印 CRS 信息（调试）
			 CoordinateReferenceSystem sourceCRS = CRS.decode("EPSG:4326");
			 CoordinateReferenceSystem targetCRS = schema.getCoordinateReferenceSystem();
			 MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS, true);

			 GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
			 Point point = geometryFactory.createPoint(new org.locationtech.jts.geom.Coordinate(longitude, latitude));
			 Point transformedPoint = (Point) JTS.transform(point, transform);

			 String filterStr = "INTERSECTS(the_geom, POINT(" + transformedPoint.getX() + " " + transformedPoint.getY() + "))";
			 Filter filter = ECQL.toFilter(filterStr);

			 SimpleFeatureCollection features = featureSource.getFeatures(filter);
			 List<Map<String, Object>> matchedFeatures = new ArrayList<>();

			 try (SimpleFeatureIterator iterator = features.features()) {
				 while (iterator.hasNext()) {
					 SimpleFeature feature = iterator.next();

					 // 获取字段值
					 Object rockType = feature.getAttribute("岩类");
					 Object rockTypeName = feature.getAttribute("岩类名称");
//					 Object descriptor = feature.getAttribute("DESCRIPTOR");
//					 Object symbol = feature.getAttribute("SYMBOL");


					 System.out.println("岩类: " + (rockType != null ? rockType.toString() : "null"));
					 System.out.println("岩类名称: " + (rockTypeName != null ? rockTypeName.toString() : "null"));

					 // 拼接两个值
					 String combinedValue = "";
					 if (rockType != null && rockTypeName != null) {
						 combinedValue = rockType.toString() + " " + rockTypeName.toString();
					 } else if (rockType != null) {
						 combinedValue = rockType.toString();
					 } else if (rockTypeName != null) {
						 combinedValue = rockTypeName.toString();
					 }

					 // 添加到结果中
					 matchedFeatures.add(Collections.singletonMap("岩组类型", combinedValue));
				 }
			 }


			 result.put("features", matchedFeatures);

		 } catch (Exception e) {
			 result.put("error", e.getMessage());
			 result.put("status", "fail");
			 e.printStackTrace();
		 } finally {
			 if (dataStore != null) {
				 dataStore.dispose();
			 }
		 }

		 return  Result.ok(result) ;
	 }



	 private static final Map<String, DataStore> dataStoreCache = new HashMap<>();
	 @ApiOperation(value = "查询岩组类型", notes = "根据坐标点查询岩组类型")
	 @PostMapping("/selectSockType")
	 public Result<Map<String, Object>>selectSockType(@RequestBody JSONObject jsonObject) {
		 double longitude = jsonObject.getDouble("longitude");
		 double latitude = jsonObject.getDouble("latitude");

		 Map<String, Object> result = new HashMap<>();


		 // 设置全局参数（只需设置一次）
		 System.setProperty("org.geotools.referencing.forceXY", "true");
		 System.setProperty("dbf.encoding", "GBK");

		 try {

			 // 2. 查询坡度数据
			 Map<String, Object> slopeResult = queryShapefile(
					 SockTypePath,
					 longitude,
					 latitude,
					 new String[]{"岩类", "岩类名称"},
					 "rockType"
			 );

			 result.putAll(slopeResult);

		 } catch (Exception e) {
			 result.put("status", "fail");
			 result.put("error", e.getMessage());
			 e.printStackTrace();
		 }

		 return Result.ok(result);
	 }
	 @ApiOperation(value = "查询坡度类型", notes = "查询坡度类型")
	 @PostMapping("/selectGeoType")
	 public Result<Map<String, Object>>selectGeoType(@RequestBody JSONObject jsonObject) {
		 double longitude = jsonObject.getDouble("longitude");
		 double latitude = jsonObject.getDouble("latitude");

		 Map<String, Object> result = new HashMap<>();

		 // 设置全局参数（只需设置一次）
		 System.setProperty("org.geotools.referencing.forceXY", "true");
		 System.setProperty("dbf.encoding", "GBK");

		 try {

			 // 2. 查询坡度数据
			 Map<String, Object> slopeResult = queryShapefile(
					 GeoTypePath,
					 longitude,
					 latitude,
					 new String[]{"gridcode"},  // 根据实际字段名调整
					 "slope"
			 );

			 result.putAll(slopeResult);

		 } catch (Exception e) {
			 result.put("status", "fail");
			 result.put("error", e.getMessage());
			 e.printStackTrace();
		 }

		 return Result.ok(result);
	 }
	 @ApiOperation(value = "查询岩组类型和地形坡度", notes = "根据坐标点查询岩组类型和地形坡度")
	 @PostMapping("/selectGeoData")
	 public Result<Map<String, Object>>queryGeoData(@RequestBody JSONObject jsonObject) {
		 double longitude = jsonObject.getDouble("longitude");
		 double latitude = jsonObject.getDouble("latitude");

		 Map<String, Object> result = new HashMap<>();

		 // 设置全局参数（只需设置一次）
		 System.setProperty("org.geotools.referencing.forceXY", "true");
		 System.setProperty("dbf.encoding", "GBK");
		 log.info("longitude: {}, latitude: {}", longitude, latitude);

		 try {
			 // 1. 查询岩组数据
			 Map<String, Object> rockTypeFuture =  queryShapefile(
							 SockTypePath,
							 longitude,
							 latitude,
							 new String[]{"岩类", "岩类名称"},
							 "rockType"
					 );

			 // 2. 查询坡度数据
		Map<String, Object> slopeFuture =  queryShapefile(
							 GeoTypePath,
							 longitude,
							 latitude,
							 new String[]{"gridcode"},  // 根据实际字段名调整
							 "slope"
					 );

			 // 合并结果
			 result.putAll(rockTypeFuture);
			 result.putAll(slopeFuture);
		 } catch (Exception e) {
			 result.put("status", "fail");
			 result.put("error", e.getMessage());
			 e.printStackTrace();
		 }
		 return Result.ok(result);
	 }


	 @ApiOperation(value = "查询岩组类型和地形坡度", notes = "根据坐标点查询岩组类型和地形坡度")
	 @PostMapping("/selectGeoData1")
	 public Result<Map<String, Object>>queryGeoData1(@RequestBody JSONObject jsonObject) {
		 double longitude = jsonObject.getDouble("longitude");
		 double latitude = jsonObject.getDouble("latitude");

		 Map<String, Object> result = new HashMap<>();

		 // 设置全局参数（只需设置一次）
		 System.setProperty("org.geotools.referencing.forceXY", "true");
		 System.setProperty("dbf.encoding", "GBK");
		 log.info("longitude: {}, latitude: {}", longitude, latitude);

		 try {
			 // 1. 查询岩组数据
			 Future<Map<String, Object>> rockTypeFuture = taskExecutor.submit(() -> {
				 try {
					 return queryShapefile(
							 SockTypePath,
							 longitude,
							 latitude,
							 new String[]{"岩类", "岩类名称"},
							 "rockType"
					 );
				 } catch (Exception e) {
					 throw new RuntimeException(e);
				 }
			 });
			 // 2. 查询坡度数据
			 Future<Map<String, Object>> slopeFuture = taskExecutor.submit(() -> {
				 try {
					 return queryShapefile(
							 GeoTypePath,
							 longitude,
							 latitude,
							 new String[]{"gridcode"},  // 根据实际字段名调整
							 "slope"
					 );
				 } catch (Exception e) {
					 throw new RuntimeException(e);
				 }
			 });
			 // 合并结果
			 result.putAll(rockTypeFuture.get());
			 result.putAll(slopeFuture.get());
		 } catch (Exception e) {
			 result.put("status", "fail");
			 result.put("error", e.getMessage());
			 e.printStackTrace();
		 }
		 return Result.ok(result);
	 }
	 @ApiOperation(value = "调用外部模型进行边坡稳定性预测", notes = "调用外部模型进行边坡稳定性预测")
	 @PostMapping(value = "/predict")
	 public Result<Map<String, Object>> predict(@RequestBody GmSlopeData gmSlopeData) {
		 try {
			 // 构建请求参数
			 Map<String, String> predictData = new HashMap<>();
			 predictData.put("切坡类型", gmSlopeData.getSlopeType());
			 predictData.put("切坡高度", gmSlopeData.getCutSlopeHeight());
			 predictData.put("切坡坡度", gmSlopeData.getCutSlopeGradient());
			 predictData.put("坡面形态", gmSlopeData.getCutSlopeShape());
			 predictData.put("自然斜坡坡度", gmSlopeData.getNaturalSlopeGradient());
			 predictData.put("土层松散程度", gmSlopeData.getSoilLooseness());
			 predictData.put("土体类型", gmSlopeData.getOverlyingSoilType());
			 predictData.put("岩组类型", gmSlopeData.getRockType());
			 predictData.put("植被覆盖率", gmSlopeData.getVegetationCoverage());
			 predictData.put("已有治理措施", gmSlopeData.getGovernanceMeasures());
			 predictData.put("岩体特征", gmSlopeData.getRockCharacteristics());
			 predictData.put("裂隙发育程度", gmSlopeData.getFractureDevelopmentDegree());

			 // 调用外部预测服务
			 String predictUrl = "http://8.148.26.149:8001/predict";
			 System.out.println("predictUrl = " + predictUrl);
			 JSONObject requestBody = new JSONObject();
			 requestBody.putAll(predictData);

			 // 发送POST请求
			 String response = sendPostRequest(predictUrl, requestBody.toJSONString());

			 // 解析响应
			 JSONObject responseObject = JSONObject.parseObject(response);
			 Map<String, Object> result = new HashMap<>();
			 result.put("prediction", responseObject);

			 return Result.OK(result);
		 } catch (Exception e) {
			 log.error("调用预测服务失败", e);
			 return Result.error("预测服务调用失败: " + e.getMessage());
		 }
	 }


	 /**
	  * 发送POST请求
	  * @param url 请求地址
	  * @param jsonBody 请求体JSON字符串
	  * @return 响应内容
	  * @throws Exception 请求异常
	  */
	 private String sendPostRequest(String url, String jsonBody) throws Exception {
		 URL obj = new URL(url);
		 HttpURLConnection con = (HttpURLConnection) obj.openConnection();
		 con.setRequestMethod("POST");
		 con.setRequestProperty("Content-Type", "application/json; utf-8");
		 con.setRequestProperty("Accept", "application/json");
		 con.setDoOutput(true);

		 try (OutputStream os = con.getOutputStream()) {
			 byte[] input = jsonBody.getBytes("utf-8");
			 os.write(input, 0, input.length);
		 }

		 try (BufferedReader br = new BufferedReader(
				 new InputStreamReader(con.getInputStream(), "utf-8"))) {
			 StringBuilder response = new StringBuilder();
			 String responseLine = null;
			 while ((responseLine = br.readLine()) != null) {
				 response.append(responseLine.trim());
			 }
			 return response.toString();
		 }
	 }




	 /**
	  * 通用Shapefile查询方法
	  *
	  * @param filePath Shapefile路径
	  * @param longitude 经度
	  * @param latitude 纬度
	  * @param attributeNames 需要查询的属性字段名
	  * @param resultKey 结果中使用的键名
	  * @return 包含查询结果的Map
	  */
//	 @Async("asyncExecutor")
	 public Map<String, Object> queryShapefile(String filePath, double longitude, double latitude,
												String[] attributeNames, String resultKey)
			 throws Exception {
		 log.info("filePath: {}, longitude: {}, latitude: {}", filePath, longitude, latitude);

		 Map<String, Object> result = new HashMap<>();
		 List<Map<String, String>> featuresList = new ArrayList<>();

		 File file = new File(filePath);
		 if (!file.exists()) {
			 result.put(resultKey + "_error", "文件不存在: " + filePath);
			 return result;
		 }

		 DataStore dataStore = getDataStore(file.toURI().toURL(), "GBK");
		 if (dataStore == null) {
			 result.put(resultKey + "_error", "无法加载数据源: " + filePath);
			 return result;
		 }
		 log.info("dataStore: {}", dataStore);

		 String typeName = dataStore.getTypeNames()[0];
		 FeatureSource featureSource = dataStore.getFeatureSource(typeName);
		 SimpleFeatureType schema = (SimpleFeatureType) featureSource.getSchema();

		 // 坐标系转换 (WGS84 -> 数据源CRS)
		 CoordinateReferenceSystem sourceCRS = CRS.decode("EPSG:4326");
		 CoordinateReferenceSystem targetCRS = schema.getCoordinateReferenceSystem();
		 MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS, true);

		 // 创建查询点
		 GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
		 Point point = geometryFactory.createPoint(new Coordinate(longitude, latitude));
		 Point transformedPoint = (Point) JTS.transform(point, transform);

		 // 构建空间查询过滤器
		 Filter filter = ECQL.toFilter(
				 "INTERSECTS(the_geom, POINT(" + transformedPoint.getX() + " " + transformedPoint.getY() + "))"
		 );

		 // 执行查询
		 SimpleFeatureCollection features = (SimpleFeatureCollection) featureSource.getFeatures(filter);
		 try (SimpleFeatureIterator iterator = features.features()) {
			 while (iterator.hasNext()) {
				 SimpleFeature feature = iterator.next();
				 Map<String, String> attributeMap = new HashMap<>();

				 // 提取所需属性
				 for (String attrName : attributeNames) {
					 Object value = feature.getAttribute(attrName);
					 attributeMap.put(attrName, value != null ? value.toString() : "N/A");
				 }
				 featuresList.add(attributeMap);
			 }
		 }

		 // 特殊处理：岩组数据拼接字段
		 if ("rockType".equals(resultKey)) {
			String combinedValues = "";
			 for (Map<String, String> attrs : featuresList) {
				 String rockType = attrs.getOrDefault("岩类", "");
				 String rockTypeName = attrs.getOrDefault("岩类名称", "");
				 combinedValues=rockType + " " + rockTypeName.trim();
			 }
			 result.put(resultKey, combinedValues);
		 }
		 // 坡度数据直接返回数值
		 else if ("slope".equals(resultKey) && !featuresList.isEmpty()) {
			 // 取第一个匹配要素的值（假设点只落在一个坡度区间）
			 String slopeValue = featuresList.get(0).get("gridcode");
			 try {
				 if(slopeValue.equals("1")){
					 result.put(resultKey, "A 小于20°".trim());
                 }else if(slopeValue.equals("2")){
					 result.put(resultKey, "B 20°-30°".trim());
                 }else {
					 result.put(resultKey, "C 大于30°".trim());
				 }
			 } catch (NumberFormatException e) {
				 result.put(resultKey, slopeValue); // 保留原始字符串值
			 }
		 } else {
			 result.put(resultKey, featuresList);
		 }

		 return result;
	 }

	 private synchronized DataStore getDataStore(URL url, String charset) throws Exception {
		 String cacheKey = url.toString();
		 if (dataStoreCache.containsKey(cacheKey)) {
			 return dataStoreCache.get(cacheKey);
		 }

		 // 准备数据存储参数
		 Map<String, Object> params = new HashMap<>();
		 params.put("url", url);
		 params.put("charset", charset);

		 DataStore dataStore = DataStoreFinder.getDataStore(params);
		 if (dataStore != null) {
			 dataStoreCache.put(cacheKey, dataStore);
		 }

		 return dataStore;
	 }



}
